use quote::ToTokens;
use syn::{Data, DeriveInput, parse_quote};
use validator::SelfValidator;
use validator::Validator;
use validator::impls::*;
use validator_expand::validator_derive::FieldAttrs;

#[test]
fn field() {
    let input: DeriveInput = parse_quote! {
        pub struct Foo {
            #[validate(regex("[a-z]+"))]
            #[validate(length(1, 10, "aabc"))]
            #[validate("无效的bar")]
            #[validate()]
            pub bar: String,
        }
    };
    if let Data::Struct(data) = input.data {
        for field in data.fields {
            let validates = FieldAttrs::try_from(&field.attrs).unwrap().validates;
            for item in validates {
                match item {
                    validator_expand::validator_derive::ValidateAttr::Length(min, max, message) => {
                        println!(
                            "length({}, {}, {})",
                            min.to_token_stream(),
                            max.to_token_stream(),
                            message.unwrap_or_default(),
                        );
                    }
                    validator_expand::validator_derive::ValidateAttr::Range(min, max, message) => {
                        println!(
                            "range({}, {}, {})",
                            min.to_token_stream(),
                            max.to_token_stream(),
                            message.unwrap_or_default(),
                        );
                    }
                    validator_expand::validator_derive::ValidateAttr::Regex(regex, message) => {
                        let a = 1;
                        let _name = format!("{a}");
                        println!("regex({}, {})", regex, message.unwrap_or_default(),);
                    }
                    validator_expand::validator_derive::ValidateAttr::Enumer(ty, message) => {
                        println!(
                            "enumer({}, {}",
                            ty.to_token_stream(),
                            message.unwrap_or_default()
                        );
                    }
                    validator_expand::validator_derive::ValidateAttr::SelfValidate(message) => {
                        println!("validator({})", message.unwrap_or_default());
                    }
                    validator_expand::validator_derive::ValidateAttr::OnlySelfValidate => {}
                    validator_expand::validator_derive::ValidateAttr::Constant(expr, message) => {
                        println!(
                            "constant({}, {})",
                            expr.to_token_stream(),
                            message.unwrap_or_default()
                        );
                    }
                }
            }
        }
    }
}

#[test]
fn test_validator_derive() {
    #[derive(Validator)]
    pub struct Student {
        #[validate(length(1, 10))]
        pub name: String,
    }
    let s = Student {
        name: "abc".to_string(),
    };
    let result = <Student as SelfValidator>::validate(&s, Some("name"), Some("名称"));
    println!("{result:?}");
}

#[test]
fn test_expand() {
    let derive_input: DeriveInput = parse_quote! {
        pub struct Student {
            #[validate(length(1, 10))]
            pub name: String,
        }
    };
    let generated = validator_expand::validator_derive::expand(&derive_input).unwrap();
    println!("{generated}");
}
